﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Common.Utilities;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.Entities.Providers
{
    public partial class SamplingEditor : Form, IComponentEditor 
    {
        private object _ActivityNode;
        private SamplingComponent _SamplingComponent;

        public SamplingEditor()
        {
            InitializeComponent();
        }

        private void SamplingEditor_Load(object sender, EventArgs e)
        {
            this.cbo_Method.Items.Clear();
            for(int i=0;i<=1;i++)
            {
                SamplingMethod method = (SamplingMethod)i;
                this.cbo_Method.Items.Add(method.ToString());
            }
        }

        #region IComponentEditor Members

        public event UpdateComponentSettings UpdateComponentSettingEvent;

        public object OwnerActivityNode
        {
            get { return _ActivityNode; }
            set { _ActivityNode = value; }
        }

        public Type WorkflowComponentType
        {
            get { return typeof (SamplingComponent); }
        }

        public void LoadSettings(GlobalVariable[] globalVars, WorkflowComponentBase[] fromComponents,
                                 object activityNode, WorkflowComponentBase wfComponent)
        {
            this._ActivityNode = activityNode;
            this._SamplingComponent = (SamplingComponent)wfComponent;

            this.txt_EntityProviderFilePath.Text = this._SamplingComponent.EntityProviderFilePath;
            this.cbo_DbProvider.SelectedIndex = (int)this._SamplingComponent.DbProvider;
            this.txt_ConnStr.Text = this._SamplingComponent.ConnStr;
            this.rt_SQL.Text = this._SamplingComponent.SelectSql;
            if (!string.IsNullOrEmpty(this._SamplingComponent.EntityProviderFilePath))
                this.rd_FileSource.Checked = true;
            else
                this.rd_DbSource.Checked = true;
            this.cbo_FilterAttr.Items.Clear();
            this.cbo_IDAttr.Items.Clear();
            if(!string.IsNullOrEmpty(this.txt_ConnStr.Text ) && !string.IsNullOrEmpty(this.rt_SQL.Text))
            {
                TableColumn[] cols =
                    DbUtil.GetTableColumns(this._SamplingComponent.DbProvider, this.txt_ConnStr.Text, this.rt_SQL.Text);
                if(cols !=null && cols.Length>0)
                {
                    foreach(TableColumn col in cols)
                    {
                        this.cbo_FilterAttr.Items.Add(col.ColumnName);
                        this.cbo_IDAttr.Items.Add(col.ColumnName);
                    }
                }
            }
            if(this.cbo_IDAttr.Items.Count>0 && !string.IsNullOrEmpty(this._SamplingComponent.IDAttributeName))
            {
                for(int i=0;i<this.cbo_IDAttr.Items.Count;i++)
                {
                    if(this.cbo_IDAttr.Items[i].ToString()==this._SamplingComponent.IDAttributeName)
                    {
                        this.cbo_IDAttr.SelectedIndex = i;
                        break;
                    }
                }
            }
            if(this.cbo_SeedAttribute.Items.Count>0 && !string.IsNullOrEmpty(this._SamplingComponent.SeedAttributeName))
            {
                for(int i=0;i<this.cbo_SeedAttribute.Items.Count;i++)
                {
                    if(this.cbo_SeedAttribute.Items[i].ToString()==this._SamplingComponent.SeedAttributeName)
                    {
                        this.cbo_SeedAttribute.SelectedIndex = i;
                        break;
                    }
                }
            }

            this.cbo_Method.SelectedIndex = (int)this._SamplingComponent.Method;
            this.num_SampleSize.Value = this._SamplingComponent.SampleSize;

            this.dv_Filters.Rows.Clear();
            if(this._SamplingComponent.Filters != null && this._SamplingComponent.Filters.Count>0)
            {
                foreach(string attrName in this._SamplingComponent.Filters.Keys)
                {
                    DataGridViewRow dr = new DataGridViewRow();
                    DataGridViewTextBoxCell cellAttrName = new DataGridViewTextBoxCell();
                    cellAttrName.Value = attrName;
                    dr.Cells.Add(cellAttrName);

                    DataGridViewTextBoxCell cellOp = new DataGridViewTextBoxCell();
                    cellOp.Value = "=";
                    dr.Cells.Add(cellOp);

                    DataGridViewTextBoxCell cellValue = new DataGridViewTextBoxCell();
                    cellValue.Value = this._SamplingComponent.Filters[attrName];
                    dr.Cells.Add(cellValue);

                    this.dv_Filters.Rows.Add(dr);
                }
            }

            if(this._SamplingComponent.RangeFilters !=null && this._SamplingComponent.RangeFilters.Count>0)
            {
                foreach(string attrName in this._SamplingComponent.RangeFilters.Keys)
                {
                    DataGridViewRow dr = new DataGridViewRow();
                    DataGridViewTextBoxCell cellAttrName = new DataGridViewTextBoxCell();
                    cellAttrName.Value = attrName;
                    dr.Cells.Add(cellAttrName);

                    DataGridViewTextBoxCell cellOp = new DataGridViewTextBoxCell();
                    cellOp.Value = "between";
                    dr.Cells.Add(cellOp);

                    DataGridViewTextBoxCell cellValue = new DataGridViewTextBoxCell();
                    Range<int> range = this._SamplingComponent.RangeFilters[attrName];
                    cellValue.Value = string.Format("{0} and {1}", range.FromValue, range.ToValue);
                    dr.Cells.Add(cellValue);

                    this.dv_Filters.Rows.Add(dr);
                }
            }

            this.txt_ResultFilePath.Text = this._SamplingComponent.SamplingResultFilePath;
        }

        public void SaveSettings()
        {
            this._SamplingComponent.EntityProviderFilePath = this.txt_ResultFilePath.Text;
            this._SamplingComponent.DbProvider = (DataProviderType)this.cbo_DbProvider.SelectedIndex;
            this._SamplingComponent.ConnStr = this.txt_ConnStr.Text;
            this._SamplingComponent.SelectSql = this.rt_SQL.Text;
            this._SamplingComponent.IDAttributeName = this.cbo_IDAttr.Text;
            this._SamplingComponent.SeedAttributeName = this.cbo_SeedAttribute.Text;

            this._SamplingComponent.Method = (SamplingMethod)this.cbo_Method.SelectedIndex;
            this._SamplingComponent.SampleSize = (int)this.num_SampleSize.Value;

            this._SamplingComponent.Filters = new Dictionary<string, string>();
            this._SamplingComponent.RangeFilters = new Dictionary<string, Range<int>>();
            foreach(DataGridViewRow dr in this.dv_Filters.Rows)
            {
                if(!dr.IsNewRow && dr.Cells[0].Value !=null )
                {
                    string attrName = dr.Cells[0].Value.ToString();
                    string op = dr.Cells[1].Value.ToString();
                    string val = dr.Cells[2].Value.ToString();
                    if(op.ToLower()=="=")
                    {
                        this._SamplingComponent.Filters.Add(attrName, val);
                    }
                    else
                    {
                        string[] pair = StringUtil.Split(val, " and ");
                        if(pair.Length==2)
                        {
                            int fromVal = int.Parse(pair[0]);
                            int toVal = int.Parse(pair[1]);
                            Range<int> range = new Range<int>();
                            range.FromValue = Math.Min(fromVal, toVal);
                            range.ToValue = Math.Max(fromVal, toVal);
                            this._SamplingComponent.RangeFilters.Add(attrName, range);
                        }
                    }
                }
            }

            this._SamplingComponent.SamplingResultFilePath = this.txt_ResultFilePath.Text;
        }

        public TestResult Test()
        {
            throw new NotImplementedException();
        }

        #endregion

        private void btn_OK_Click(object sender, EventArgs e)
        {
            this.SaveSettings();

            if (this.UpdateComponentSettingEvent != null)
                this.UpdateComponentSettingEvent(this._ActivityNode, this._SamplingComponent);

            this.Close();
        }

        private void btn_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btn_Update_Click(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(this.txt_ConnStr.Text) && !string.IsNullOrEmpty(this.rt_SQL.Text))
            {
                this.cbo_FilterAttr.Items.Clear();
                this.cbo_IDAttr.Items.Clear();
                this.cbo_SeedAttribute.Items.Clear();
                TableColumn[] cols =
                    DbUtil.GetTableColumns(this._SamplingComponent.DbProvider, this.txt_ConnStr.Text, this.rt_SQL.Text);
                if (cols != null && cols.Length > 0)
                {
                    foreach (TableColumn col in cols)
                    {
                        this.cbo_FilterAttr.Items.Add(col.ColumnName);
                        this.cbo_IDAttr.Items.Add(col.ColumnName);
                        this.cbo_SeedAttribute.Items.Add(col.ColumnName);
                    }
                }
            }
        }

        private void rd_Equal_CheckedChanged(object sender, EventArgs e)
        {
            if(this.rd_Equal.Checked)
            {
                this.lbl_And.Visible = false;
                this.txt_Value2.Visible = false;
            }
            else
            {
                this.lbl_And.Visible = true;
                this.txt_Value2.Visible = true;
            }
        }

        private void rd_Within_CheckedChanged(object sender, EventArgs e)
        {
            if (this.rd_Equal.Checked)
            {
                this.lbl_And.Visible = false;
                this.txt_Value2.Visible = false;
            }
            else
            {
                this.lbl_And.Visible = true;
                this.txt_Value2.Visible = true;
            }
        }

        private void btn_AddFilter_Click(object sender, EventArgs e)
        {
            if(this.cbo_FilterAttr.SelectedIndex>=0)
            {
                string attrName = this.cbo_FilterAttr.SelectedItem.ToString();
                string op = "=";
                string val = this.txt_Value1.Text;
                if (this.rd_Within.Checked)
                {
                    op = "between";
                    val = string.Format("{0} and {1}", this.txt_Value1.Text, this.txt_Value2.Text);
                }

                DataGridViewRow dr = new DataGridViewRow();
                DataGridViewTextBoxCell cellAttrName = new DataGridViewTextBoxCell();
                cellAttrName.Value = attrName;
                dr.Cells.Add(cellAttrName);
                DataGridViewTextBoxCell cellOp = new DataGridViewTextBoxCell();
                cellOp.Value = op;
                dr.Cells.Add(cellOp);
                DataGridViewTextBoxCell cellVal = new DataGridViewTextBoxCell();
                cellVal.Value = val;
                dr.Cells.Add(cellVal);
                this.dv_Filters.Rows.Add(dr);
            }
        }

        private void btn_BrowseDataSource_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "Entity provider files(*.xml)|*.xml|All files(*.*)|*.*";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                this.txt_EntityProviderFilePath.Text = dlg.FileName;
            }
        }

        private void btn_SaveOutput_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "Sampling result files(*.xml)|*.xml|All files(*.*)|*.*";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                this.txt_ResultFilePath.Text = dlg.FileName;
            }
        }
    }
}
